package com.zhdl.modules.puncturecable.web.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.project.common.util.WebResult;
import com.zhdl.modules.puncturecable.service.PunctureCableService;
import com.zhdl.modules.puncturecable.web.PunctureCableProcess;
import com.zhdl.modules.tools.CommonCallback;
import com.zhdl.modules.wallpulley.web.resp.TensileDistanceSseResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping(path = "/punctureCable", produces = MediaType.APPLICATION_JSON_VALUE)
public class PunctureCableController {

    @Resource
    private PunctureCableProcess punctureCableProcess;

    @Resource
    private PunctureCableService punctureCableService;

    /**
     * 机器人抓料单点
     *
     * @param instructName 指令名称
     */
    @GetMapping("robotPickAction")
    public WebResult<String> robotPickAction(String instructName){
        int instruct = -1;
        switch (instructName){
            case "原点" -> {
                instruct = 0;
            }
            case "上方抓" -> {
                instruct = 1;
            }
            case "上方放" -> {
                instruct = 2;
            }
            case "抓" -> {
                instruct = 3;
            }
            case "安全点" -> {
                instruct = 4;
            }
            case "放料上" -> {
                instruct = 5;
            }
            case "放料" ->{
                instruct = 6;
            }
        }
        punctureCableService.robotSendPickAction("192.168.58.2:8080",instruct, s -> {
            log.info("当前放料指令为-->" + instructName);
        });
        return WebResult.okResult("当前放料指令为-->" + instructName + ",运动完成");
    }

    /**
     * 首页数据请求
     */
    @GetMapping(value = "/sse/{id}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter handleSse(@PathVariable Integer id) {
        log.info(id.toString());
        SseEmitter emitter = new SseEmitter();
        sseEmitters.put(id, emitter);
        // 超时移除
        emitter.onTimeout(() -> {
            emitter.complete();
            sseEmitters.remove(id);
        });
        // 完成移除
        emitter.onCompletion(() -> sseEmitters.remove(id));
        // 每一秒发送一条消息
        executorService.scheduleAtFixedRate(() -> {
            ObjectMapper mapper = new ObjectMapper();
            //加载内存数据
            WebResult<TensileDistanceSseResp> sseResp =WebResult.okResult(punctureCableProcess.tensileDistanceSseResp);
            punctureCableProcess.tensileDistanceSseResp = new TensileDistanceSseResp();
            try {
                emitter.send(SseEmitter.event().id(String.valueOf(getSseSeq())).data(mapper.writeValueAsString(sseResp), MediaType.APPLICATION_JSON));
                log.info("send" + sseResp);
            } catch (IOException e) {
                emitter.complete();
            }
        }, 0, 1, TimeUnit.SECONDS);

        return emitter;
    }



    private long sseSeq;
    private static final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();

    private final Map<Integer, SseEmitter> sseEmitters = new ConcurrentHashMap<>();

    /**
     * 获取SSE序号
     */
    private long getSseSeq() {
        if (sseSeq > 65535L * 65535) sseSeq = 0;
        return sseSeq++;
    }


    @GetMapping("/testRun1")
    public WebResult<String> testRun1(boolean runDone){
        punctureCableProcess.pickStartProcess(runDone);
        return WebResult.okResult("Robot pick point already run!");
    }
    @GetMapping("/testRun2")
    public WebResult<String> testRun2(boolean runDone){
        punctureCableProcess.putStartProcess(runDone);
        return WebResult.okResult("Robot pick point already run!");
    }


    /**
     * 机器人抓料流程
     * @param model 当前流程
     */
    @GetMapping("/robotPickRun")
    public WebResult<String> robotPickRun(int model){
//        punctureCableProcess.tempRun(model);
        return WebResult.okResult("Robot pick point already run!");
    }

    @GetMapping("/test")
    public WebResult<String> test(int model){
//        punctureCableProcess.tempRun(model);
        return WebResult.okResult("run Success!");
    }
}
